package com.zh.common.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import com.blankj.utilcode.util.ScreenUtils
import com.zh.common.ktx.dp2px
import com.zh.common.ktx.vibrateSearch
import kotlin.math.abs

/**
 * 仿夸克输入框移动光标
 */
class TouchSeekView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    enum class LoadType(type: Int) {
        TYPE_DEFAULT(0),
        TYPE_SELECT(1),
        TYPE_TOUCH(2);
    }

    private var loadType = LoadType.TYPE_DEFAULT

    //默认情况
    private val defaultBgColor = Color.parseColor("#DDDDDD")
    private val defaultBgWidth = 36f.dp2px.toFloat()
    private val defaultBgHeight = 10f.dp2px.toFloat()
    private val defaultSeekColor = Color.parseColor("#CCCCCC")
    private val seekRadius = 10f.dp2px.toFloat()

    //选中情况
    private val selectBgColor = Color.parseColor("#DDDDDD")
    private val selectSeekColor = Color.parseColor("#FEFFFE")

    private val paddingLR = 30f.dp2px.toFloat()//左右两边padding

    //touch情况seek宽度
    private val touchBgWidth by lazy { ScreenUtils.getScreenWidth() - paddingLR }

    private var textLength = 0//文字长度
    var touchStatus: ((isTouch: Boolean) -> Unit)? = null//touch状态回调
    var backIndexLeftOrRight: ((isLeft: Boolean) -> Unit)? = null//返回左右移动回调

    //切分多少份，用与光标计算
    private var spaceSize = 0
    private var sWidth = 0f//每一份需要移动的宽度
    private var moveX = 0f//有正负值，分左右

    private val paint by lazy {
        Paint().apply {
            isAntiAlias = true
            strokeCap = Paint.Cap.ROUND
            style = Paint.Style.FILL
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        var mW = 0
        var mH = 0
        if (loadType == LoadType.TYPE_DEFAULT || loadType == LoadType.TYPE_SELECT) {
            mW = defaultBgWidth.toInt()
            mH = defaultBgWidth.toInt()
        } else if (loadType == LoadType.TYPE_TOUCH) {
            mW = touchBgWidth.toInt()
            mH = defaultBgWidth.toInt()
            sWidth = touchBgWidth / spaceSize
        }
        setMeasuredDimension(mW, mH)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (loadType == LoadType.TYPE_TOUCH) {
            paint.color = defaultBgColor
            drawableFullBg(canvas)
            paint.color = selectSeekColor
            drawableSmallSeek(canvas)
        } else {
            if (loadType == LoadType.TYPE_DEFAULT) {
                paint.color = defaultBgColor
                drawableSmallBg(canvas)
                paint.color = defaultSeekColor
                drawableSmallSeek(canvas)
            } else if (loadType == LoadType.TYPE_SELECT) {
                paint.color = selectBgColor
                drawableSmallBg(canvas)
                paint.color = selectSeekColor
                drawableSmallSeek(canvas)
            }
        }
    }

    private fun drawableFullBg(canvas: Canvas) {
        canvas.drawRoundRect(
            0f,
            height / 2 - defaultBgHeight / 2,
            touchBgWidth,
            height / 2 + defaultBgHeight / 2,
            defaultBgHeight / 2f, defaultBgHeight / 2f, paint
        )
    }

    private fun drawableSmallBg(canvas: Canvas) {
        //默认时候背景
        canvas.drawRoundRect(
            0f,
            height / 2 - defaultBgHeight / 2,
            defaultBgWidth,
            height / 2 + defaultBgHeight / 2,
            defaultBgHeight / 2f, defaultBgHeight / 2f, paint
        )
    }

    private fun drawableSmallSeek(canvas: Canvas) {
        if (moveX == 0f) {
            canvas.drawCircle(width / 2f, height / 2f, seekRadius, paint)
        } else {
            var cx = width / 2f + moveX
            cx = if (cx + seekRadius < 0) 0f else cx
            cx = if (cx - seekRadius > 0) cx - seekRadius else cx
            //默认滑块
            canvas.drawCircle(cx, height / 2f, seekRadius, paint)
        }
    }

    fun changeStatus(status: LoadType, textLength: Int) {
        loadType = status
        this.textLength = textLength
        spaceSize = textLength * 2 + 21
        moveX = 0f
        invalidate()
    }

    private var dx = 0f
    private var currentX = 0f//移动后定位x
    private var isFirstTouch = false

    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (textLength == 0) {
            touchStatus?.invoke(false)
            return true
        }
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                dx = event.x
                context.vibrateSearch()
                loadType = LoadType.TYPE_TOUCH
                changeWidth(true)
                touchStatus?.invoke(true)
                isFirstTouch = true
                return true
            }

            MotionEvent.ACTION_MOVE -> {
                if (width.toFloat() == defaultBgWidth) return true
                val mx = if (event.x < paddingLR / 2 + seekRadius / 2) {
                    paddingLR / 2 + seekRadius / 2
                } else if (event.x > width) {
                    width.toFloat()
                } else {
                    event.x
                }
                if (isFirstTouch) {//第一次按下，重置x坐标
                    isFirstTouch = false
                    dx = width / 2f
                } else {//回调位置
                    if (mx - currentX > 0) {// 向右移动
                        if (abs(mx - currentX) >= sWidth && currentX != mx) {
                            currentX = mx
                            backIndexLeftOrRight?.invoke(false)
                        }
                    } else if (mx - currentX < 0) {//向左移动
                        if (abs(mx - currentX) >= sWidth && currentX != mx) {
                            currentX = mx
                            backIndexLeftOrRight?.invoke(true)
                        }
                    }
                }

                moveX = mx - dx
                invalidate()
                return true
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                loadType = LoadType.TYPE_SELECT
                changeWidth(false)
                touchStatus?.invoke(false)
                isFirstTouch = true
                return true
            }
        }
        return super.onTouchEvent(event)
    }

    private fun changeWidth(full: Boolean) {
        if (full) {//按下

        } else {//松开
            moveX = 0f
        }
        requestLayout()
        invalidate()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
    }
}